<?php
// +----------------------------------------------------------------------
// | Description: 组织架构
// +----------------------------------------------------------------------
// | Author:
// +----------------------------------------------------------------------

namespace app\admin\model;

use app\common\traits\ActionRecordTrait;
use think\facade\Db;

class Structure extends Common
{

    use ActionRecordTrait;

    /**
     * 为了数据库的整洁，同时又不影响Model和Controller的名称
     * 我们约定每个模块的数据表都加上相同的前缀，比如CRM模块用crm作为数据表前缀
     */
    protected $name = 'admin_structure';

    /**
     * [getDataList 获取列表]
     * @return    [array]
     */
    public function getDataList($type='',$param = [])
    {
        $cat = new \com\Category('admin_structure', array('id', 'pid', 'name', 'title'));
        $map = [];
        if (isset($param['search']) && $param['search']) {
            // $map['user.username|user.realname'] = ['like', '%'.$map['search'].'%'];
            $map[] = ['name', 'like', '%'.$param['search'].'%'];
        }
        $data = $cat->getList($map, 0, 'sort ASC');
        if ($data) {
            foreach ($data as $k => $v) {
                $v['create_time'] = $v['create_time'] ? date('Y-m-d H:i:s', $v['create_time']) : '';
                $v['update_time'] = $v['update_time'] ? date('Y-m-d H:i:s', $v['update_time']) : '';
                $data[$k] = $v;
            }
        }
        // 若type为tree，则返回树状结构
        if ($type == 'tree') {
            $tree = new \com\Tree();
            $data = $tree->list_to_tree($data, 'id', 'pid', 'child', 0, true, array(''));
        }
        return $data;
    }

    /*
    *根据字符串展示参与部门 use by work
    *add by yykun
    */
    public function getDataByStr($idstr)
    {
        $isArr = stringToArray($idstr);
        if (!$isArr) {
            return false;
        }
        $list = $this->field('id as structure_id,name')->where(['id' => ['in',$isArr]])->select();
        return $list;
    }

    /*
    *根据部门ID获取信息 use by work
    */
    public function getDataByID( $id ='')
    {
        $det = Db::name('AdminStructure')->where('id','=',$id)->find();
        return $det;
    }


    /**
     * 根据id获取等级
     * @param string $id
     * @return array|false|\think\Model|null
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     * @author Mr.Li
     * @create 2021-07-08 14:20
     */
    public function getLevelByID( $id ='')
    {
        $level = Db::name('AdminStructure')->where('id','=',$id)->value('level');
        return $level;
    }


    public function delStrById($id)
    {
        if (!$id) {
            $this->error = '删除失败';
            return false;
        }
        $dataInfo = $this->getDataByID($id);
        if (empty($dataInfo['pid'])) {
            $this->error = '删除失败';
            return false;
        }
        //部门是否被使用
        $allStrIds = [];
        $allStrIds[] = $id;
        $allSubStrIds = $this->getAllChild($id);

        $allStrIds = array_merge($allStrIds, $allSubStrIds); //全部关联部门（包含下属部门）
        $resUser = Db::name('AdminUser')->where('structure_id','in',$allStrIds)->find();
        if ($resUser) {
            $this->error = '该部门或其下属部门已存在员工，不能删除';
            return false;
        }
        if(Db::name('AdminStructure')->where('pid','=',$id)->value('id')){
            $this->error = '该部门存在下级部门,不能删除';
            return false;
        }
        $resDel = $this->delDataById($id, true);
        if (!$resDel) {
            $this->error = '删除失败';
            return false;
        } else {
            return true;
        }
    }

    /**
     * [getStructureNameByArr 根据主键获取详情]
     * @param     string     $id [主键]
     * @return    [array]
     */
    public function getStructureNameByArr($ids = [])
    {
        if (!is_array($ids)) {
            $idArr[] = $ids;
        } else {
            $idArr = $ids;
        }
        $data = $this->where(['id' => array('in', $idArr)])->column('name');
        return $data ? : [];
    }

    /*
    *根据字符串展示参与部门 use by work
    *add by yykun
    */
    public function getListByStr($str)
    {
        $idArr = stringToArray($str);
        $list = $this->field('id,name')->where(['id' => ['in',$idArr]])->select();
        return $list;
    }

    /**
     * 详情
     * @param  array $request 请求参数
     * @return array
     * @author Mr.Liu Wuchen
     * @create 2021-07-28 10:01
     */
    public function getDataInfo(array $request): array
    {
        try {
            $id = $request['id'] ?? 0;
            if (!$id) {
                $this->error = '参数错误';
                return [];
            }

            $field = ['id', 'name', 'pid', 'sort', 'remark', 'create_user_id', 'create_time', 'update_time'];
            $info  = $this->where(['id' => $id])->field($field)->find();
            if (!$info) {
                $this->error = '部门信息不存在';
                return [];
            }

            $info['create_user_name'] = Db::name('admin_user')->where(['id' => $info['create_user_id']])->value('realname', '');
            $info['parent_name']      = $this->where(['id' => $info['pid']])->value('name');
            unset($info['create_user_id'], $info['pid']);

            $this->error = '获取成功';
            return $info->toArray();
        } catch (\Exception $e) {
        }

        $this->error = '编辑失败';
        return [];
    }

    /**
     * 添加
     * @param  array $request 请求参数
     * @return bool
     * @author Mr.Liu Wuchen
     * @create 2021-07-27 15:58
     */
    public function addData(array $request): bool
    {
        try {
            $request['name']   = isset($request['name']) ? trim($request['name']) : '';
            $request['remark'] = isset($request['remark']) ? trim($request['remark']) : '';
            $request['sort']   = isset($request['sort']) ? intval($request['sort']) : 0;
            $validate = new \app\admin\validate\Structure();
            if (!$validate->scene('create')->check($request)) {
                $this->error = $validate->getError();
                return false;
            }

            // 判断部门下是否有区域设置
            $isConfirm = isset($request['is_confirm']) ? intval($request['is_confirm']) : 0;
            $pid       = intval($request['pid']);
            if (!$isConfirm) {
                $region    = Db::name('admin_structure_region')->where('structure_id', '=', $pid)->find();
                if ($region) {
                    header('Content-Type:application/json; charset=utf-8');
                    exit(json_encode(['code' => 101, 'error' => '当前部门存在区域设置，创建下属部门时将清除该区域设置，确定继续操作吗？']));
                }
            }

            $pid     = intval($request['pid']);
            $pidInfo = $this->where('id', '=', $pid)->field(['id', 'pid', 'level', 'pid_level'])->find();
            $level   = $pidInfo['level'] ?? 1;
            // if ($level == 6) {
            //     $this->error = '部门最多可以存在6层下级';
            //     return false;
            // }

            $pid == 1 && $pidInfo['pid_level'] = '-';
            $pidLevel = $pidInfo['pid_level'] . $pid . '-';
            $data = [
                'name'           => $request['name'],
                'pid'            => $pid,
                'level'          => $level + 1,
                'sort'           => $request['sort'],
                'remark'         => $request['remark'],
                'create_user_id' => $request['user_id'],
                'pid_level'      => $pidLevel,
                'create_time'    => time(),
                'update_time'    => time()
            ];
            $structureId = $this->insertGetId($data);
            if ($structureId) {
                // 删除部门地区表关联数据
                Db::name('admin_structure_region')->where('structure_id', '=', $pid)->delete();

                // 添加操作记录
                $logCode = json_encode($data, JSON_UNESCAPED_UNICODE);
                $this->addActionRecord($request['user_id'], 'admin_structure_create', $structureId, '创建了部门', 'admin', 'structure', $logCode);

                $this->error = '添加成功';
                return true;
            }
        } catch (\Exception $e) {
        }

        $this->error = '添加失败';
        return false;
    }

    /**
     * 编辑
     * @param  array $request 请求参数
     * @return bool
     * @author Mr.Liu Wuchen
     * @create 2021-07-27 16:25
     */
    public function saveData(array $request): bool
    {
        try {
            $request['id']     = isset($request['id']) ? intval($request['id']) : 0;
            $request['name']   = isset($request['name']) ? trim($request['name']) : '';
            $request['remark'] = isset($request['remark']) ? trim($request['remark']) : '';
            $request['sort']   = isset($request['sort']) ? intval($request['sort']) : 0;
            $validate = new \app\admin\validate\Structure();
            if (!$validate->scene('update')->check($request)) {
                $this->error = $validate->getError();
                return false;
            }

            $field = ['id', 'name', 'sort', 'remark'];
            $info  = $this->where('id', '=', $request['id'])->field($field)->find();
            if (!$info) {
                $this->error = '部门信息不存在';
                return false;
            }
            if ($info['id'] == 1) {
                $this->error = '顶级部门不能编辑';
                return false;
            }

            $data = [
                'name'        => $request['name'],
                'sort'        => $request['sort'],
                'remark'      => $request['remark'],
                'update_time' => time()
            ];
            $bool = $this->where('id', '=', $request['id'])->update($data);
            if ($bool) {
                // 添加操作记录
                $logFieldArr = [
                    'name'   => '部门名称',
                    'sort'   => '排序',
                    'remark' => '备注',
                ];
                $logContentArr = [];
                foreach ($logFieldArr as $key => $val) {
                    if ($data[$key] != $info[$key]) {
                        $logContentArr[] = "将 '" . $val . "' 由 " . $info[$key] . " 修改为 " . $data[$key];
                    }
                }
                if ($logContentArr) {
                    $logData       = $data;
                    $logContentStr = implode('.|.', $logContentArr);
                    $logCode       = json_encode($logData, JSON_UNESCAPED_UNICODE);
                    $this->addActionRecord($request['user_id'], 'admin_structure_update', $request['id'], $logContentStr, 'admin', 'structure', $logCode);
                }

                $this->error = '编辑成功';
                return true;
            }
        } catch (\Exception $e) {
        }

        $this->error = '编辑失败';
        return false;
    }

    /**
     * 删除
     * @param  array $request 请求参数
     * @return bool
     * @author Mr.Liu Wuchen
     * @create 2021-07-28 9:55
     */
    public function deleteData(array $request): bool
    {
        try {
            $id = isset($request['id']) && intval($request['id']) ? intval($request['id']) : 0;
            if (!$id) {
                $this->error = '参数错误';
                return false;
            }

            $field = ['id'];
            $info  = $this->where('id', '=', $id)->field($field)->find();
            if (!$info) {
                $this->error = '部门信息不存在';
                return false;
            }

            //部门是否被使用
            $allStrIds    = [$id];
            $allSubStrIds = $this->getAllChild($id);
            $allStrIds    = array_merge($allStrIds, $allSubStrIds); //全部关联部门（包含下属部门）
            $resUser      = Db::name('admin_user')->where('structure_id', 'in', $allStrIds)->find();
            if ($resUser) {
                $this->error = '该部门或其下属部门存在员工，无法删除';
                return false;
            }
            if($this->where('pid', '=', $id)->value('id')) {
                $this->error = '该部门存在下级部门,不能删除';
                return false;
            }

            // 删除
            $bool = $this->where('id', 'in', $allStrIds)->delete();
            if ($bool) {
                // 删除部门地区表关联数据
                Db::name('admin_structure_region')->where('structure_id', 'in', $allStrIds)->delete();

                // 添加操作记录
                $list  = $this->where('id', 'in', $allStrIds)->select()->toArray();
                foreach ($list as $key => $val) {
                    $logCode = json_encode($val, JSON_UNESCAPED_UNICODE);
                    $this->addActionRecord($request['user_id'], 'admin_structure_delete', $val['id'], '删除了部门', 'admin', 'structure', $logCode);
                }

                $this->error = '删除成功';
                return true;
            }
        } catch (\Exception $e) {
        }

        $this->error = '删除失败';
        return false;
    }

    /**
     * 操作记录
     * @param  array $request 请求参数
     * @return array
     * @author Mr.Liu Wuchen
     * @create 2021-07-28 11:31
     */
    public function getRecordList(array $request): array
    {
        $id = $request['id'] ?? 0;
        if (!$id) {
            $this->error = '参数错误';
            return [];
        }

        $page  = isset($request['page']) && intval($request['page']) ? intval($request['page']) : 1;
        $limit = isset($request['limit']) && intval($request['limit']) ? intval($request['limit']) : 15;
        return $this->getActionRecordListByPage($id, 'admin', 'structure', 0, $page, $limit);
	}

    /**
     * 迁移选择部门
     * @param  array $request 请求参数
     * @return array
     * @author Mr.Liu Wuchen
     * @create 2021-07-29 15:40
     */
    public function getSelectStructureData(array $request): array
    {
        try {
            $id    = isset($request['id']) && intval($request['id']) ? intval($request['id']) : 0;
            $where = [];
            if ($id) {
                // 获取本部门以下部门
                $allStrIds    = [$id];
                $allSubStrIds = $this->getAllChild($id);
                $allStrIds    = $allSubStrIds ? array_merge($allStrIds, $allSubStrIds) : $allStrIds; //全部关联部门（包含下属部门）
                array_push($where, ['id', 'not in', $allStrIds]);
            } else {
                array_push($where, ['id', '<>', $id]);
            }
            $field = ['id', 'name'];
            $list  = $this->where($where)->field($field)->select()->toArray();

            $this->error  = '获取成功';
            $data['data'] = $list ?: [];
            return $data;
        } catch (\Exception $e) {
        }

        $this->error = '暂无数据';
        return [];
	}

	/**
     * 迁移选择直属上级
     * @param  array $request 请求参数
     * @return array
     * @author Mr.Liu Wuchen
     * @create 2021-07-29 15:40
     */
    public function getSelectParentData(array $request): array
    {
        try {
            $id       = isset($request['id']) && intval($request['id']) ? intval($request['id']) : 0;
            $targetId = isset($request['target_id']) && intval($request['target_id']) ? intval($request['target_id']) : 0;
            if (!$id) {
                $this->error = '参数错误';
                return [];
            }
            if (!$targetId) {
                $this->error = '请先选择上级部门';
                return [];
            }
            // 获取所有直属上级
            $pidArr = $this->getAllParent($targetId);
            array_push($pidArr, $id);
            $where = [
                ['structure_id', 'in', array_unique($pidArr)],
                ['status', '<>', 0]
            ];
            $field = ['id', 'realname'];
            $list  = Db::name('admin_user')->where($where)->field($field)->select()->toArray();

            $this->error  = '获取成功';
            $data['data'] = $list ?: [];
            return $data;
        } catch (\Exception $e) {
        }

        $this->error = '暂无数据';
        return [];
	}

    /**
     * 迁移
     * @param  array $request 请求参数
     * @return bool
     * @author Mr.Liu Wuchen
     * @create 2021-07-29 15:16
     */
	public function moveData(array $request): bool
    {
        try {
            $authType = isset($request['auth_type']) && intval($request['auth_type']) ? intval($request['auth_type']) : 1; // 权限设置 1：保留 2：默认权限
            $syncType = isset($request['sync_type']) && intval($request['sync_type']) ? intval($request['sync_type']) : 1; // 同步设置 1：同步迁移 2：异步迁移
            $parentId = isset($request['parent_user_id']) && intval($request['parent_user_id']) ? intval($request['parent_user_id']) : 0; // 直属上级
            $targetId = isset($request['target_id']) && intval($request['target_id']) ? intval($request['target_id']) : 0; // 迁移的目标 上级部门ID
            $asyncId  = isset($request['async_id']) && intval($request['async_id']) ? intval($request['async_id']) : 0; // 异步迁移 部门ID
            $id       = isset($request['id']) && intval($request['id']) ? intval($request['id']) : 0; // 当前需要迁移的部门ID
            if (!$id) {
                $this->error = '参数错误';
                return false;
            }
            if (!$targetId) {
                $this->error = '请选择上级部门';
                return false;
            }
            if (!$parentId) {
                $this->error = '请选择员工直属上级';
                return false;
            }
            !in_array($authType, [1, 2]) && $authType = 1;
            !in_array($syncType, [1, 2]) && $syncType = 1;
            if ($syncType == 2 && !$asyncId) {
                $this->error = '请选择员工需要迁移的部门';
                return false;
            }

            // 判断部门
            $field   = ['id', 'name', 'pid', 'pid_level', 'level'];
            $infoArr = $this->where('id', 'in', [$id, $targetId])->field($field)->column($field, 'id');
            if (!$infoArr) {
                $this->error = '部门信息不存在';
                return false;
            }
            $info       = isset($infoArr[$id]) && $infoArr[$id] ? $infoArr[$id] : [];
            $targetInfo = isset($infoArr[$targetId]) && $infoArr[$targetId] ? $infoArr[$targetId] : [];
            if (!$info || !$targetInfo) {
                $this->error = '部门信息不存在';
                return false;
            }

            // 判断选择的上级部门是否符合
            $list     = $this->getSelectStructureData(['id' => $id]);
            $listData = isset($list['data']) && $list['data'] ? array_column($list['data'], 'id') : [];
            if (!in_array($targetId, $listData)) {
                $this->error = '选择上级部门不合规则，请刷新后重试';
                return false;
            }

            // 判断选择的直属上级是否符合
            $list     = $this->getSelectParentData(['id' => $id, 'target_id' => $targetId]);
            $listData = isset($list['data']) && $list['data'] ? array_column($list['data'], 'id') : [];
            if (!in_array($parentId, $listData)) {
                $this->error = '选择直属上级不合规则，请刷新后重试';
                return false;
            }

            // 获取本部门以下部门
            $allStrIds    = [$id];
            $allSubStrIds = $this->getAllChild($id);
            $allStrIds    = array_merge($allStrIds, $allSubStrIds); //全部关联部门（包含下属部门）
        } catch (\Exception $e) {
            $this->error = '迁移失败';
            return false;
        }

        Db::startTrans();
        try {
            // 更新本部门以及下属部门的员工的直属上级
            if ($allStrIds) {
                $bool = Db::name('admin_user')->where('structure_id', 'in', $allStrIds)->update(['parent_id' => $parentId]);
                if ($bool >= 0) {
                } else {
                    throw new \Exception('更新员工直属上级失败');
                }
            }

            // 获取本部门下的员工
            $userIdArr = Db::name('admin_user')->where('structure_id', '=', $id)->column('id');
            if (in_array($parentId, $userIdArr)) {
                // 直属上级存在本部门中 则设置为 超级管理员
                $bool = Db::name('admin_user')->where('id', '=', $parentId)->update(['parent_id' => 1]);
                if ($bool >= 0) {
                } else {
                    throw new \Exception('更新本部门中员工直属上级失败');
                }
            }

            $pidLevelNew = $targetInfo['pid_level'] . $targetId . '-'; // 新 pid_level
            $levelNew    = $targetInfo['level'] + 1;

            // 更新迁移部门
            $data = [
                'pid'         => $targetId,
                'level'       => $levelNew,
                'pid_level'   => $pidLevelNew,
                'update_time' => time()
            ];
            $bool = $this->where('id', '=', $id)->update($data);
            if (!$bool) {
                throw new \Exception('更新上级部门失败');
            }

            // 更新当前部门的全部下级的部门 pid_level
            // $field = ['id', 'pid_level'];
            // $list  = $this->where('pid_level', 'like', '%-' . $id . '-%')->field($field)->select()->toArray();
            // if ($list) {
            //     $boolNum = 0;
            //     foreach ($list as $key => $val) {
            //         $pidLevel = strtr($val['pid_level'], $info['pid_level'], $pidLevelNew);
            //         $level    = substr_count($pidLevel, '-');
            //         $data = [
            //             'level'       => $level,
            //             'pid_level'   => $pidLevel,
            //             'update_time' => time()
            //         ];
            //         $bool = $this->where('id', '=', $val['id'])->update($data);
            //         if ($bool) {
            //             $boolNum++;
            //         }
            //     }
            //     if ($boolNum != count($list)) {
            //         throw new \Exception('更新下级部门 pid_level 失败');
            //     }
            // }

            // 全表更新部门结构
            $bool = $this->updatePidLevel();
            if (!$bool) {
                throw new \Exception('更新下级部门 pid_level 失败');
            }

            // 更新员工权限设置 为默认权限
            if ($authType == 2) {
                $userList  = Db::name('admin_user')->where('structure_id', 'in', $allStrIds)->select()->toArray();
                $userIdArr = array_column($userList, 'id');
                // 删除原角色 添加默认角色
                Db::name('admin_access')->where('user_id', 'in', $userIdArr)->delete();
                $accessData = [];
                foreach ($userIdArr as $key => $val) {
                    $accessData[] = [
                        'user_id'  => $val,
                        'group_id' => 2,
                    ];
                }
                $insertNum = Db::name('admin_access')->insertAll($accessData);
                if (!$insertNum) {
                    throw new \Exception('更新员工权限失败');
                }
            }

            // 删除部门地区表关联数据
            Db::name('admin_structure_region')->where('structure_id', '=', $targetId)->delete();

            // 添加操作记录
            $higherName      = Db::name('admin_user')->where('id', '=', $parentId)->value('realname', '');
            $nowName         = $this->where('id', '=', $info['pid'])->value('name', '');
            $logContentArr[] = "部门迁移";
            $logContentArr[] = "将 '上级部门' 由 " . $nowName . " 修改为 " . $targetInfo['name'];
            $logContentArr[] = "将 '直属上级' 修改为 " . $higherName;
            $authType == 2 && $logContentArr[] = "将 '员工角色' 修改为 默认角色";
            $logContentStr   = implode('.|.', $logContentArr);
            $logCode         = json_encode($request, JSON_UNESCAPED_UNICODE);
            $this->addActionRecord($request['user_id'], 'admin_structure_move', $id, $logContentStr, 'admin', 'structure', $logCode);

            Db::commit();

            $this->error = '迁移成功';
            return true;
        } catch (\Exception $e) {
            Db::rollback();
            $this->error = $e->getMessage();
        }

        return false;
    }

    /**
     * 批量更新已有数据 pid_level
     * @return bool
     * @author Mr.Liu Wuchen
     * @create 2021-07-31 11:46
     */
    public function updatePidLevel(): bool
    {
        set_time_limit(0);
        try {
            $levelArr = $this->where('id', '<>', 1)->column('level');
            $levelArr = array_unique($levelArr);
            sort($levelArr);
            foreach ($levelArr as $key => $val) {
                $list = $this->where(['level' => $val])->select()->toArray();
                foreach ($list as $k => $v) {
                    $pid = $v['pid'];
                    $pidInfo = $this->where('id', '=', $pid)->find();
                    $pid == 1 && $pidInfo['pid_level'] = '-';
                    $pidLevel = $pidInfo['pid_level'] . $pid . '-';
                    $data = [
                        'pid_level'   => $pidLevel,
                        // 'update_time' => time()
                    ];
                    $this->where('id', '=', $v['id'])->update($data);
                }
            }

            // 更新 level
            $list = $this->where('id', '<>', 1)->select();
            foreach ($list as $key => $val) {
                $level = substr_count($val['pid_level'], '-');
                $this->where('id', '=', $val['id'])->update(['level' => $level]);
            }
        } catch (\Exception $e) {
            // print_r($e->getMessage());
            return false;
        }
        // print_r('更新完成');
        return true;
	}

	/**
     * 添加、编辑部门区域
     * @param  array $request 请求参数
     * @return bool
     * @author SL
     * @create 2021-07-30 16:25
     */
    public function saveRegionData(array $request): bool
    {
        try {
            $id = isset($request['id']) && intval($request['id']) ? intval($request['id']) : 0;
            if (!$id) {
                $this->error = '参数错误';
                return false;
            }

            $region_ids = isset($request['region_ids']) ? $request['region_ids'] : [];

            $field = ['id', 'name'];
            $info  = $this->where('id', '=', $id)->field($field)->find();
            if (!$info) 
            {
                $this->error = '部门信息不存在';
                return false;
            }

            $ids = $this->where(['pid' => $id])->column('id');
            if( count($ids) )
            {
                $this->error = '不是最后一级部门,不能绑定区域';
                return false;
            }
            /*$uniqueList = [];
            $list       = [];
            foreach($region_ids as $key => $val) {
                $list[$val[0]][] = [$val[1], $val[2]];
                array_push($uniqueList, implode(',', $val));
            }
            if (count(array_unique($uniqueList)) != count($uniqueList)) {
                // 有重复数据
                echo '有重复数据';
                return false;
            }

            foreach($list as $key => $val) {
                $group = [];
                foreach($val as $k => $v) {
                    $group[$v[0]][] = $v[1];
                }
                if (array_key_exists(0, $group) && count($group) > 1) {
                    // 不符合条件 【1 0 0】  【1 2 3】
                    echo '不符合条件 【1 0 0】  【1 2 3】';
                    return false;
                }

                foreach($group as $kk => $vv) {
                    if (in_array(0, $vv) && count($vv) > 1) {
                        // 不符合条件 【1 2 0】  【1 2 3】
                        echo '不符合条件 【1 2 0】  【1 2 3】';
                        return false;
                    }
                }
            }*/
            $uniqueList = [];
            foreach($region_ids as $key => $val) {
                array_push($uniqueList, implode(',', $val));
            }
            if (count(array_unique($uniqueList)) != count($uniqueList)) {
                // 有重复数据
                $this->error = '区域异常';
                return false;
            }

            foreach ($region_ids as $key => $value) 
            {
                if( count($value) != 3 || $value[0] == 0 || ($value[0] != 0 && $value[1] == 0 && $value[2] != 0))
                {
                    $this->error = '区域异常';
                    return false;
                }
                foreach ($region_ids as $k => $v) 
                {
                    if($value == $v)
                    {
                        $v[0] = 0;
                        $v[1] = 0;
                    }

                    if($value[0] == 0 && $value[1] == 0)
                    {
                        // 不能再出现该省
                        if($value[0] == $v[0])
                        {
                            // 不符合条件 【1 0 0】  【1 2 3】
                            $this->error = '区域异常';
                            return false;
                        }
                    }
                    else if($value[2] == 0)
                    {
                        // 不能再出现该省、市
                        if($value[0] == $v[0] && $value[1] == $v[1])
                        {
                            // 不符合条件 【1 2 0】  【1 2 3】
                            $this->error = '区域异常';
                            return false;
                        }
                    }
                    else{

                    }
                }
            }

            $region = Db::name('shop_region')->select()->toArray();
            $region = array_column($region, null, 'id');
            $updateData = [];
            foreach($region_ids as $kk => $vv)
            {
                $data['structure_id']   = $id;
                $data['province_id']    = isset($vv[0]) ? $vv[0] : 0;
                $data['province_name']  = isset($region[$vv[0]]['name']) ? $region[$vv[0]]['name'] : '';
                $data['city_id']        = isset($vv[1]) ? $vv[1] : 0;
                $data['city_name']      = isset($region[$vv[1]]['name']) ? $region[$vv[1]]['name'] : '';
                $data['district_id']    = isset($vv[2]) ? $vv[2] : 0;
                $data['district_name']  = isset($region[$vv[2]]['name']) ? $region[$vv[2]]['name'] : '';
                $data['add_time']       = time();
                $data['area_code']      = implode('-', $vv);
                $data['area_name']      = $data['province_name'];
                $data['last_area']      = $data['province_id'];
                if($data['city_name'])
                {
                    $data['area_name'] = $data['area_name'] . '-' . $data['city_name'];
                    $data['last_area'] = $data['city_id'];
                }
                if($data['district_name'])
                {
                    $data['area_name'] = $data['area_name'] . '-' . $data['district_name'];
                    $data['last_area'] = $data['district_id'];
                }
                $updateData[] = $data;
            }
            // 查询该部门绑定的区域
            $oldRegion = Db::name('admin_structure_region')->where('structure_id', '=', $id)->column('area_name');
            // 删除该部门绑定的区域
            $res = Db::name('admin_structure_region')->where('structure_id', '=', $id)->delete();
            // 处理插入数据
            if($region_ids)
            {
                $bool = Db::name('admin_structure_region')->insertAll($updateData);
            }

            if($oldRegion)
            {
                $oldRegion = implode('.|.', $oldRegion);
            }
            else{
                $oldRegion = '无';
            }
            $newRegion = implode('.|.', array_column($updateData, 'area_name'));
            $logContentStr = "区域由 ' ". $oldRegion . " ' 修改为 ' " . $newRegion;
            $logData = [];
            $logData['region_ids'] = $region_ids;
            $logData['oldRegion'] = $oldRegion;
            $logCode       = json_encode($logData, JSON_UNESCAPED_UNICODE);
            $this->addActionRecord($request['user_id'], 'admin_structure_region', $request['id'], $logContentStr, 'admin', 'structure', $logCode);
            
            $this->error = '操作成功';
            return true;
            
        } catch (\Exception $e) {
            print_r($e->getMessage());
        }

        $this->error = '操作失败';
        return false;
    }

    /**
     * 区域列表
     * @param  array $request 请求参数
     * @return array
     * @author Mr.Liu Wuchen
     * @create 2021-07-31 14:10
     */
    public function getRegionData(array $request): array
    {
        try {
            $id = $request['id'] ?? 0;
            if (!$id) {
                $this->error = '参数错误';
                return [];
            }

            $field = ['id'];
            $info  = $this->where(['id' => $id])->field($field)->find();
            if (!$info) {
                $this->error = '部门不存在';
                return [];
            }

            // 判断是否当前最后一级部门
            $info['is_last_level'] = 0;
            $ids = $this->where(['pid' => $id])->column('id');
            if( !count($ids) )
            {
                $info['is_last_level'] = 1; // 最后一级

                $map = [];
                $map = [
                    ['structure_id', '=', $id]
                ];
            }
            else{
                $where = [
                    ['pid_level', 'like', '%-' . $id . '-%']
                ];
                $structure = $this->where($where)->column('id');
                $map = [
                    ['structure_id', 'in', $structure]
                ];
            }
            $region = Db::name('admin_structure_region')->where($map)->select()->toArray();
            $region_ids = array_unique(array_column($region, 'area_code'));
            $list = [];
            if($region_ids)
            {
                foreach($region_ids as $k => $v)
                {
                    $list[] = $region[$k];
                }
            }
            
            $info['list'] = $list;
            $this->error = '获取成功';
            return $info->toArray();
        } catch (\Exception $e) {
        }

        $this->error = '获取失败';
        return [];
    }

    /**
     * 获取员工部门地区
     * @param  int $userId 员工ID
     * @return array
     * @author Mr.Liu Wuchen
     * @create 2021-08-04 16:16
     */
    public function getStructureArea(int $userId = 0): array
    {
        $return = [-1];
        if (!$userId) {
            return $return;
        }
        // 获取数据权限
        $dataAuthTypeArr = (new \app\admin\model\User())->getDataAuthType($userId, 'leads');
        if (in_array(-1, $dataAuthTypeArr) || in_array('all', $dataAuthTypeArr)) {
            return $dataAuthTypeArr;
        }
        $dataAuthType = $dataAuthTypeArr[0];

        // 获取数据权限最大值
        // 1本人，2本人及下属，3本部门，4本部门及下属部门，5全部
        switch ($dataAuthType) {
            case 2:
                $nextUser = getSubUser($userId);
                $userIds  = $nextUser && is_array($nextUser) ? $nextUser : [];
                array_unshift($userIds, $userId);
                break;
            case 1:
            case 3:
            case 4:
                $userIds = [$userId];
                break;
            case 5:
                $userIds = ['all'];
                break;
            default:
                $userIds = [];
                break;
        }

        if (!$userIds) {
            return $return;
        }
        if (in_array('all', $userIds)) {
            return ['all'];
        }

        // 部门ID
        $structureIdList = Db::name('admin_user')->where('id', 'in', $userIds)->column('structure_id');
        if (!$structureIdList) {
            return [];
        }
        // 获取部门下级 部门
        $structureIdArr = [];
        foreach ($structureIdList as $key => $val) {
            $where = [
                ['pid_level', 'like', '%-' . $val . '-%']
            ];
            $structureId    = $this->where($where)->whereOr('id', '=', $val)->column('id');
            $structureIdArr = array_merge($structureIdArr, $structureId);
        }
        $structureIdArr = array_unique($structureIdArr);
        if (!$structureIdArr) {
            return $return;
        }

        // 获取部门区域ID
        $where = [
            ['structure_id', 'in', $structureIdArr]
        ];
        $areaIdArr = Db::name('admin_structure_region')->where($where)->column('last_area');
        return $areaIdArr ? array_unique($areaIdArr) : [-1];
    }

    /**
     * 获取部门
     * @param  array $provinceIdArr
     * @param  string $type
     * @return array
     * @author Mr.Liu Wuchen
     * @create 2021-08-21 10:40
     */
    public function getStructureOrUserByProvince(array $provinceIdArr, string $type = 'structure'): array
    {
        $strWhere = [
            ['province_id', 'in', $provinceIdArr]
        ];
        $regionStructureIdArr = Db::name('admin_structure_region')->where($strWhere)->column('structure_id');
        if ($regionStructureIdArr) {
            $pidLevelArr = $this->where('id', 'in', array_unique($regionStructureIdArr))->column('pid_level');
        }
        $structureIdArr = [];
        if (isset($pidLevelArr) && $pidLevelArr) {
            foreach ($pidLevelArr as $key => $val) {
                $preIdArr       = array_values(array_filter(explode('-', $val)));
                $structureIdArr = array_merge($structureIdArr, $preIdArr);
            }
        }
        $regionStructureIdArr && $structureIdArr = array_unique(array_merge($structureIdArr, $regionStructureIdArr));
        $structureIdArr = $structureIdArr ? array_unique($structureIdArr) : [];
        if ($type == 'structure') {
            // 返回部门ID
            $return = $structureIdArr;
        } else if ($type == 'user') {
            // 返回用户ID
            $where = [
                ['structure_id', 'in', $structureIdArr]
            ];
            $return = Db::name('admin_user')->where($where)->column('id');
        } else {
            $return = [];
        }
        return array_unique($return);
    }

}